const ace = require('brace');
require('brace/mode/json');
require('brace/mode/xml');
require('brace/theme/tomorrow');

function run(options) {
  options = options || {};

  const container = options.container || 'mock-editor';

  const data = options.data || '';
  options.readOnly = options.readOnly || false;
  options.fullScreen = options.fullScreen || false;

  const editor = ace.edit(container);

  editor.setTheme('ace/theme/tomorrow');
  editor.$blockScrolling = Infinity;
  editor.getSession().setMode('ace/mode/json');
  if (options.readOnly === true) {
    editor.setReadOnly(true);
    editor.renderer.$cursorLayer.element.style.display = 'none';
  }
  editor.setOptions({
    useWorker: true,
    tabSize: options.tabSize || 3,
    wrap: options.wrap ? 'free' : undefined,
  });
  editor._fullscreen_yapi = options.fullScreen;

  function handleData(data) {
    data = data || '';
    if (typeof data === 'string') {
      return data;
    }
    if (typeof data === 'object') {
      return JSON.stringify(data, null, '  ');
    }
    throw new Error('handleData');
  }

  const mockEditor = {
    curData: {},
    getValue: () => editor.getValue(),
    setValue(data) {
      editor.setValue(handleData(data));
      editor.clearSelection();
    },
    getSession() {
      return editor.getSession();
    },
    editor,
    options,
    insertCode: code => {
      const pos = editor.selection.getCursor();
      editor.session.insert(pos, code);
    },
  };

  mockEditor.setValue(handleData(data));
  // serialize(editor.getValue(), mockEditor);

  editor.clearSelection();

  editor.getSession().on('change', () => {
    // serialize(editor.getValue(), mockEditor);
    if (typeof options.onChange === 'function') {
      options.onChange.call(mockEditor, {
        text: editor.getValue(),
      });
    }
    editor.clearSelection();
  });

  return mockEditor;
}

export default run;
